<link rel="import" href="../polymer/polymer.html">
<script src="./Sortable.js"></script>

<dom-module id="sortable-js">
	<template>
		<content></content>
	</template>
</dom-module>
<script>
	Polymer({
				is: "sortable-js",

				properties: {
					group: {type: String, value: () = > Math.random(), observer: "groupChanged"
				},
				sort: {type: Boolean, value: true, observer: "sortChanged"},
				disabled: {type: Boolean, value: false, observer: "disabledChanged"},
				store: {type: Object, value: null, observer: "storeChanged"},
				handle: {type: String, value: null, observer: "handleChanged"},
				scrollSensitivity: {type: Number, value: 30, observer: "scrollSensitivityChanged"},
				scrollSpeed: {type: Number, value: 10, observer: "scrollSpeedChanged"},
				ghostClass: {type: String, value: "sortable-ghost", observer: "ghostClassChanged"},
				chosenClass: {type: String, value: "sortable-chosen", observer: "chosenClassChanged"},
				ignore: {type: String, value: "a, img", observer: "ignoreChanged"},
				filter: {type: Object, value: null, observer: "filterChanged"},
				animation: {type: Number, value: 0, observer: "animationChanged"},
				dropBubble: {type: Boolean, value: false, observer: "dropBubbleChanged"},
				dragoverBubble: {type: Boolean, value: false, observer: "dragoverBubbleChanged"},
				dataIdAttr: {type: String, value: "data-id", observer: "dataIdAttrChanged"},
				delay: {type: Number, value: 0, observer: "delayChanged"},
				forceFallback: {type: Boolean, value: false, observer: "forceFallbackChanged"},
				fallbackClass: {type: String, value: "sortable-fallback", observer: "fallbackClassChanged"},
				fallbackOnBody: {type: Boolean, value: false, observer: "fallbackOnBodyChanged"},
				manuallyHandleUpdateEvents: {type: Boolean, value: false},
				draggable: {},
				scroll: {}
			},

			created()
	{
		// override default DOM property behavior
		Object.defineProperties(this, {
			draggable: {
				get() {
					return this._draggable || this.getAttribute("draggable") || ">*"
				}, set(value) {
					this._draggable = value;
					this.draggableChanged(value)
				}
			},
			scroll: {
				get() {
					return this._scroll || JSON.parse(this.getAttribute("scroll") || "true")
				}, set(value) {
					this._scroll = value;
					this.scrollChanged(value)
				}
			}
		})
	}
	,

	attached: function () {
		// Given
		//   <sortable-js>
		//     <template is="dom-repeat" items={{data}}>
		//       <div>
		//         <template is="dom-if" if="true">
		//           <span>hello</span></template></div>
		// After render, it becomes
		//   <sortable-js>
		//     <div>
		//       <span>hello</span>
		//       <template is="dom-if">
		//     <tempalte is="dom-repeat">

		this.initialize();

	}
	,

	detached: function () {
		this.destroy()
	}
	,


	initialize: function () {

		var templates = this.querySelectorAll("template[is='dom-repeat']")
		var template = templates[templates.length - 1]

		var options = {}
		Object.keys(this.properties).forEach(key = > {
			options[key] = this[key]
		}
	)

		this.sortable = Sortable.create(this, Object.assign(options, {
					onUpdate: e = > {
					if (template) {
						if (manuallyHandleUpdateEvents) {
							template.items.splice(e.newIndex, 0, template.items.splice(e.oldIndex, 1)[0]);
						} else {
							template.splice("items", e.newIndex, 0, template.splice("items", e.oldIndex, 1)[0])
						}
					}
					this.fire("update", e)
	},

		onAdd: e =
	>
		{
			if (template) {
				var froms = e.from.querySelectorAll("template[is='dom-repeat']")
				var from = froms[froms.length - 1]
				var item = from.items[e.oldIndex]
				template.splice("items", e.newIndex, 0, item)
			}
			this.fire("add", e)
		}
	,

		onRemove: e =
	>
		{
			if (template) {
				template.splice("items", e.oldIndex, 1)[0]
			}
			this.fire("remove", e)
		}
	,

		onStart: e =
	>
		{
			this.fire("start", e)
		}
	,

		onEnd: e =
	>
		{
			this.fire("end", e)
		}
	,

		onSort: e =
	>
		{
			this.fire("sort", e)
		}
	,

		onFilter: e =
	>
		{
			this.fire("filter", e)
		}
	,

		onMove: e =
	>
		{
			this.fire("move", e)
		}
	}))

	}
	,

	destroy: function () {
		if (this.sortable) {
			this.sortable.destroy()
		}
	}
	,

	groupChanged             : function (value) {
		this.sortable && this.sortable.option("group", value)
	}
	,
	sortChanged              : function (value) {
		this.sortable && this.sortable.option("sort", value)
	}
	,
	disabledChanged          : function (value) {
		this.sortable && this.sortable.option("disabled", value)
	}
	,
	storeChanged             : function (value) {
		this.sortable && this.sortable.option("store", value)
	}
	,
	handleChanged            : function (value) {
		this.sortable && this.sortable.option("handle", value)
	}
	,
	scrollChanged           : function (value) {
		this.sortable && this.sortable.option("scroll", value)
	}
	,
	scrollSensitivityChanged : function (value) {
		this.sortable && this.sortable.option("scrollSensitivity", value)
	}
	,
	scrollSpeedChanged       : function (value) {
		this.sortable && this.sortable.option("scrollSpeed", value)
	}
	,
	draggableChanged        : function (value) {
		this.sortable && this.sortable.option("draggable", value)
	}
	,
	ghostClassChanged        : function (value) {
		this.sortable && this.sortable.option("ghostClass", value)
	}
	,
	chosenClassChanged       : function (value) {
		this.sortable && this.sortable.option("chosenClass", value)
	}
	,
	ignoreChanged            : function (value) {
		this.sortable && this.sortable.option("ignore", value)
	}
	,
	filterChanged            : function (value) {
		this.sortable && this.sortable.option("filter", value)
	}
	,
	animationChanged         : function (value) {
		this.sortable && this.sortable.option("animation", value)
	}
	,
	dropBubbleChanged        : function (value) {
		this.sortable && this.sortable.option("dropBubble", value)
	}
	,
	dragoverBubbleChanged    : function (value) {
		this.sortable && this.sortable.option("dragoverBubble", value)
	}
	,
	dataIdAttrChanged        : function (value) {
		this.sortable && this.sortable.option("dataIdAttr", value)
	}
	,
	delayChanged             : function (value) {
		this.sortable && this.sortable.option("delay", value)
	}
	,
	forceFallbackChanged     : function (value) {
		this.sortable && this.sortable.option("forceFallback", value)
	}
	,
	fallbackClassChanged     : function (value) {
		this.sortable && this.sortable.option("fallbackClass", value)
	}
	,
	fallbackOnBodyChanged    : function (value) {
		this.sortable && this.sortable.option("fallbackOnBody", value)
	}
	})
</script>
